package com.teamsun.service;

import com.teamsun.datasource.DynamicDataSource;
import com.teamsun.entity.AccessIn;
import com.teamsun.entity.DBCfg;
import com.teamsun.mapper.*;
import com.teamsun.util.Constants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>报表信息管理</p>
 */
public class RptMgrServiceImpl implements IRptMgrService{

    @Autowired
    private RptMgrMapper rptMgrMapper;

    @Autowired
    private RptMgrMySQLMapper rptMgrMySQLMapper;

    @Autowired
    private DBCfgMapper dbCfgMapper;

    @Autowired
    private DBCfgMySQLMapper dbCfgMySQLMapper;

    @Autowired
    private AccessInMapper accessInMapper;

    @Autowired
    private AccessInMySQLMapper accessInMySQLMapper;

    @Autowired
    private DynamicDataSource dynamicDataSource;

    /**
     * 分页查询报表配置信息
     * @param param 查询条件
     * @param startIndex 起始行
     * @param endIndex 结束行
     * @return
     */
    @Override
    public Map<String, Object> queryRptInfoByPage(Map<String, Object> param, int startIndex, int endIndex) {
        Map<String, Object> resultMap = new HashMap<String, Object>();

        // 分页查询报表数据
        param.put("endIndex", endIndex);
        param.put("startIndex", startIndex);
        String rptName = (String) param.get("rptName");
        if(StringUtils.isNotBlank(rptName)) {
            rptName = "%" + rptName + "%";
            param.put("rptName", rptName);
        }
        String dbType = dynamicDataSource.getMasterDBType();
        List<Map<String, Object>> rptInfos = new ArrayList<Map<String, Object>>();
        int totalCount = 0;
        if(Constants.DBTYPE_MYSQL.equalsIgnoreCase(dbType)) {
            int offset = startIndex - 1;
            int rows = endIndex - offset;
            param.put("offset", offset);
            param.put("rows", rows);
            // 主数据库为MySQL
            rptInfos = rptMgrMySQLMapper.queryRptInfoByPage(param);

            // 查询报表总数
            totalCount = rptMgrMySQLMapper.queryRptCount(param);
        } else {
            // 主数据库为Oracle
            rptInfos = rptMgrMapper.queryRptInfoByPage(param);

            // 查询报表总数
            totalCount = rptMgrMapper.queryRptCount(param);
        }


        resultMap.put("rows", rptInfos);
        resultMap.put("total", totalCount);
        return resultMap;
    }

    /**
     * 通过数据源ID查询报表
     * @param rptDBId  数据源ID
     * @return
     */
    @Override
    public List<Map<String, Object>> queryRptByDBId(String rptDBId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("dbId", rptDBId);
        return rptMgrMapper.queryRptByDBId(param);
    }

    /**
     * 通过接入系统查询报表
     * @param sysCode  接入系统代码
     * @return
     */
    @Override
    public List<Map<String, Object>> queryRptByAccessIn(String sysCode) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("sysCode", sysCode);
        return rptMgrMapper.queryRptBySysCode(param);
    }

    /**
     * 删除报表信息
     * @param param 删除条件
     */
    @Override
    public void deleteRptInfo(Map<String, Object> param) {
        rptMgrMapper.deleteRptInfo(param);
    }

    /**
     * 分页查询数据库配置信息
     * @param param 查询条件
     * @param startIndex 起始行
     * @param endIndex 结束行
     * @return
     */
    @Override
    public Map<String, Object> queryDBCfgByPage(Map<String, Object> param, int startIndex, int endIndex) {
        Map<String, Object> resultMap = new HashMap<String, Object>();

        // 分页查询报表数据
        param.put("endIndex", endIndex);
        param.put("startIndex", startIndex);
        String dbName = (String) param.get("dbName");
        if(StringUtils.isNotBlank(dbName)) {
            dbName = "%" + dbName + "%";
            param.put("dbName", dbName);
        }

        String dbType = dynamicDataSource.getMasterDBType();
        List<Map<String, Object>> dbCfgs = new ArrayList<Map<String, Object>>();
        int dbcfgCount = 0;
        if(Constants.DBTYPE_MYSQL.equalsIgnoreCase(dbType)) {
            int offset = startIndex - 1;
            int rows = endIndex - offset;
            param.put("offset", offset);
            param.put("rows", rows);
            dbCfgs = dbCfgMySQLMapper.queryDBCfgByPage(param);

            // 查询数据库配置个数
            dbcfgCount = dbCfgMySQLMapper.queryDBCfgCount(param);
        } else {
            dbCfgs = dbCfgMapper.queryDBCfgByPage(param);

            // 查询数据库配置个数
            dbcfgCount = dbCfgMapper.queryDBCfgCount(param);
        }


        resultMap.put("rows", dbCfgs);
        resultMap.put("total", dbcfgCount);
        return resultMap;
    }

    /**
     * 通过数据源名称查询数据源信息
     * @param dbName  数据源名称
     * @return
     */
    @Override
    public List<DBCfg> queryDBCfgByDBName(String dbName) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("dbName", dbName);
        return dbCfgMapper.queryDBCfg(param);
    }

    /**
     * 新增数据库配置
     * @param dbCfg
     */
    @Override
    public void addDBCfg(DBCfg dbCfg) {
        dbCfgMapper.saveDBCfg(dbCfg);

        // 防止有缓存同名的数据源，删除缓存中相关的数据源信息
        dynamicDataSource.removeDataSource(dbCfg.getDbName());
    }

    /**
     * 更新数据库配置信息
     * @param dbCfg
     */
    @Override
    public void updateDBCfg(DBCfg dbCfg) {
        String dbType = dynamicDataSource.getMasterDBType();
        if(Constants.DBTYPE_MYSQL.equalsIgnoreCase(dbType)) {
            dbCfgMySQLMapper.updateDBCfg(dbCfg);
        } else {
            dbCfgMapper.updateDBCfg(dbCfg);
        }

        // 防止有缓存同名的数据源，删除缓存中相关的数据源信息
        dynamicDataSource.removeDataSource(dbCfg.getDbName());
    }

    /**
     * 删除数据库配置信息
     * @param param
     */
    @Override
    public void deleteDBCfg(Map<String, Object> param) {
        dbCfgMapper.deleteDBCfg(param);
        String dbName = (String) param.get("dbName");

        // 删除缓存中的数据源信息
        dynamicDataSource.removeDataSource(dbName);
    }

    /**
     * 查询接入系统信息
     * @param param 查询条件
     * @param startIndex 起始行
     * @param endIndex 结束行
     * @return
     */
    @Override
    public Map<String, Object> queryAccessInByPage(Map<String, Object> param, int startIndex, int endIndex) {
        Map<String, Object> resultMap = new HashMap<String, Object>();

        // 分页查询报表接入系统
        param.put("endIndex", endIndex);
        param.put("startIndex", startIndex);
        String sysName = (String) param.get("sysName");
        if(StringUtils.isNotBlank(sysName)) {
            sysName = "%" + sysName + "%";
            param.put("sysName", sysName);
        }

        String dbType = dynamicDataSource.getMasterDBType();
        List<Map<String, Object>> accessIns = new ArrayList<Map<String, Object>>();
        int accessInCount = 0;
        if(Constants.DBTYPE_MYSQL.equalsIgnoreCase(dbType)) {
            int offset = startIndex - 1;
            int rows = endIndex - offset;
            param.put("offset", offset);
            param.put("rows", rows);
            accessIns = accessInMySQLMapper.queryAccessInByPage(param);

            // 查询报表接入系统个数
            accessInCount = accessInMySQLMapper.queryAccessInCount(param);
        } else {
            accessIns = accessInMapper.queryAccessInByPage(param);

            // 查询报表接入系统个数
            accessInCount = accessInMapper.queryAccessInCount(param);
        }

        resultMap.put("rows", accessIns);
        resultMap.put("total", accessInCount);
        return resultMap;
    }

    /**
     * 通过接入系统代码查询接入系统
     * @param sysCode 接入系统代码
     * @return
     */
    @Override
    public List<AccessIn> queryAccessInByCode(String sysCode) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("sysCode", sysCode);
        return accessInMapper.queryAccessIn(param);
    }

    /**
     * 删除接入系统信息
     * @param param 限制条件
     */
    @Override
    public void deleteAccessIn(Map<String, Object> param) {
        accessInMapper.deleteAccessIn(param);
    }

    /**
     * 新增接入系统信息
     * @param accessIn
     */
    @Override
    public void addAccessIn(AccessIn accessIn) {
        accessInMapper.saveAccessIn(accessIn);
    }

    /**
     * 修改接入系统信息
     * @param accessIn
     * @param needUpdateRpt
     * @param oldSysCode
     */
    @Override
    @Transactional
    public void updateAccessIn(AccessIn accessIn, boolean needUpdateRpt, String oldSysCode) {
        String dbType = dynamicDataSource.getMasterDBType();
        if(Constants.DBTYPE_MYSQL.equalsIgnoreCase(dbType)) {
            accessInMySQLMapper.updateAccessIn(accessIn);
        } else {
            accessInMapper.updateAccessIn(accessIn);
        }

        if(needUpdateRpt) {
            // 如果修改了接入系统代码，则需要同步修改报表对应的系统代码
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("sysCode", accessIn.getSysCode());
            param.put("oldCode", oldSysCode);
            rptMgrMapper.updateRptSys(param);
        }
    }

    /**
     * 修改接入系统token
     * 更新接入系统token时，需同步更新接入系统相关报表的token信息
     * @param param
     */
    @Override
    @Transactional
    public void updateSysToken(Map<String, Object> param) {
        accessInMapper.updateAccessToken(param);

        // 更新接入系统对应的报表Token
        rptMgrMapper.updateRptToken(param);
    }

    /**
     * 根据接入系统ID查询接入系统信息
     * @param sysId 接入系统ID
     * @return
     */
    @Override
    public List<AccessIn> queryAccessInById(String sysId) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("sysId", sysId);
        List<AccessIn> accessIns = accessInMapper.queryAccessIn(param);
        return accessIns;
    }
}
